# -*- coding: utf-8 -*-
# @Author: Cursor
# @Date: 2025-01-04
# @Last Modified by: Tim Liu
# @Last Modified time: 2024-01-04

# @Description: base processor for document ingestion

from typing import Dict, Optional
import logging

from crewplus.apps.rag.utils.document_util import get_file_type_from_url

from crewplus.apps.rag.processors.base_processor import DocumentProcessor  
from crewplus.apps.rag.schemas.ingest_request import IngestRequest

from langchain_core.vectorstores.base import VectorStore
from langchain_core.embeddings import Embeddings

class DocumentProcessorDispatcher:
    def __init__(self):
        # Dictionary to hold processors based on (file_type, source_type) tuples
        self.processors: Dict[tuple, DocumentProcessor] = {}
        self.vector_store = None
        self.embeddings = None

    def register(self, file_type: str, source_type: str, processor: DocumentProcessor):
        """Register a processor for a specific file type and source type combination."""
        self.processors[(file_type, source_type)] = processor

    def bind_vstore(self, vector_store: VectorStore, embeddings: Optional[Embeddings]):
        """Bind the vector store and embeddings to the dispatcher."""
        self.vector_store = vector_store
        self.embeddings = embeddings

    async def dispatch(self, message: IngestRequest, collection_name: str):
        """Dispatch the processing to the appropriate processor based on file type and source type."""
        # Determine the file type and source type from the message
        file_type = message.file_type
        source_type = message.source_type
        logging.info(f"file_type:{file_type}")
        logging.info(f"source_type:{source_type}")
        # If file_type is not provided or is an empty string, determine it from the URL
        if not file_type:
            file_type = get_file_type_from_url(message.url)
            if not file_type:
                raise ValueError("Unable to determine file type from URL")
        logging.info("file_type start")
        # Get the appropriate processor
        processor = self.processors.get((file_type, source_type))
        logging.info("file_type end")
        if processor:
            return await processor.process(message, collection_name, self.vector_store, self.embeddings)
        else:
            raise ValueError("Unsupported file type or source type combination")